/*
 * Solution.java
 *
 * Created on 15 December, 2008, 3:58 AM
 *@author Pranay
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package vrp;

import java.util.LinkedList;

/**
 *
 * @author Pranay
 */
public class Solution {
    
    private int numVehicles;
    private double cost = 0.0, length = 0.0;
    private Vehicle firstVehicle;
    private LinkedList<Move> movesPerformed= new LinkedList<Move>();
    
    /** Creates a new instance of Solution */
    public Solution() {
    }
    
    void setLength(double l) {
        length=l;
    }
    
    double getLength() {
        return length;
    }
    
    void updateLength(double updater) {
        length+=updater;
    }

    /**
     * Perform a move in the given solution
     * @param move
     */
    void perform(Move move) {
        move.getCustomer().deleteSelf();
        move.getFinalCar().addCustomer(move.getCustomer(),move.getFinalPosition());
        cost=move.getCost();
        movesPerformed.add(move);
        length+=move.getLength();
        // Recalculate customers' position in the initialCar and in the final one
        move.getInitCar().getFirstCustomer().setPosition(0);
        move.getFinalCar().getFirstCustomer().setPosition(0);
    }    

    void clearMovesPerformed() {
        movesPerformed.clear();
    }

    int getNumVehicles() {
        return numVehicles;
    }

    Vehicle getFirstVehicle() {
        return firstVehicle;
    }

    double getCost() {
        return cost;
    }
    
	public void setCost(double cost) {
		this.cost = cost;
	}
	
    /**
     * Generate the best solution thanks to the latest performed moves
     */
    void generateBestSol() {
    	// Note : we have to create a copy of the list because "perform" is adding elements in it
    	// Otherwise a ConcurrentModificationException is thrown
    	LinkedList<Move> movesPerformedCopy = new LinkedList<Move>(this.movesPerformed);
    	for(Move move:movesPerformedCopy){
    		move.inverseMove();
    		perform(move);
    	}
    }

    void setFirstVehicle(Vehicle nextCar) {
        firstVehicle=nextCar;
    }

    void decNumVehiclesby1() {
        --numVehicles;
    }
    
	public void setNumVehicles(int i) {
		this.numVehicles = i;
	}

    /**
     * Method permitting to write the solution to the screen for debugging purposes
     */
    public void printDebug(){
    	// Recap lines
    	System.out.println("*********************************************");
    	System.out.println("*************** DEBUG SOLUTION **************");
    	System.out.println("Number of vehicles : "+this.numVehicles);
    	System.out.println("Cost of the solution : "+this.cost);
    	// Start to show the rounds
    	Vehicle currVehicle = this.firstVehicle;
    	while(currVehicle != null){
    		currVehicle.printDebug();
    		System.out.println();
    		currVehicle = currVehicle.getNextCar();
    	}
    }

    /**
     * Gives the global overflow (capacity violation) of the current solution
     * @return Current capacity violation
     */
	public int getQ() {
		int q = 0;
		Vehicle currVehicle = this.firstVehicle;
		while(currVehicle != null){
			if(currVehicle.getUsage() > Constants.carCapacity){
				q += currVehicle.getUsage() - Constants.carCapacity;
			}
			currVehicle = currVehicle.getNextCar();
		}
		return q;
	}


}
